package com.siyi.fpvdemo;

import static com.siyi.fpvdemo.Mk15Key.*;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

import com.sixtyplus.semen.boardapp.board.serialport.HexUtil;
import com.sixtyplus.semen.boardapp.board.serialport.ISerialPortMgr;
import com.sixtyplus.semen.boardapp.board.serialport.SerialPortMgr;
import com.siyi.imagetransmission.connection.ConnectionManager;
import com.siyi.imagetransmission.connection.ConnectionListener;
import com.siyi.imagetransmission.contract.protocol.DeviceInfo;
import com.siyi.imagetransmission.contract.protocol.IRCProtocolListener;
import com.siyi.imagetransmission.contract.protocol.Param24G;
import com.siyi.imagetransmission.contract.protocol.Param58G;
import com.siyi.imagetransmission.contract.protocol.e;
import com.siyi.imagetransmission.decoder.DecodeConfig;
import com.siyi.imagetransmission.log.Logcat;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private SerialPortMgr mSerialPortMgr;
    private Map<Integer, Mk15Key> s_mkkeys;
    private Timer mTimer;
    private TimerTask mTimerTask = null;
    private static Handler mMsgHandler;
    private boolean isReadDevId = false;
    private static boolean isVideoShow = false;
    private ConnectionManager mConnectionManager;

    public static void videoQuit() {
        isVideoShow = false;
        System.out.println("Video page is quit!");
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setHideVirtualKey(getWindow());

        setContentView(R.layout.activity_state);
        initTextLabel();
        mMsgHandler = new Handler() {
            @SuppressLint({"HandlerLeak", "DefaultLocale"})
            public void handleMessage(Message msg){
                byte[] data = (byte[])msg.obj;
                switch (msg.what) {
                    case 0x04: {
                        if (0x01 == data[6]) {
                            showMessage("电源控制执行成功");
                        }
                    }
                    break;
                    case 0x05: {
                        if (0x01 == data[5]) {
                            mMsgHandler.sendEmptyMessage(0x0501);
                            System.out.println("获取控制器成功");
                            Toast.makeText(getApplicationContext(), "获取控制器成功", Toast.LENGTH_SHORT).show();
                            startTimer();
                        }

                        if (0x00 == data[5]) {
                            System.out.println("释放控制器成功");
                            Toast.makeText(getApplicationContext(), "机器人控制权限释放失败", Toast.LENGTH_SHORT).show();
                            stopTimer();
                        }

                        if (0x02 == data[5]) {
                            // 控制权获取失败不允许地面站接入
                            System.out.println("控制权获取失败不允许地面站接入");
                            Toast.makeText(getApplicationContext(), "控制权获取失败不允许地面站接入", Toast.LENGTH_SHORT).show();
                        }

                        if (0x03 == data[5]) {
                            TextView view = (TextView)findViewById(R.id.label_state);
                            if (null == view) return;
                            view.setText("控制端: 地面站释放");
                            // 地面站控制器释放
                            System.out.println("释放控制器成功");
                            Toast.makeText(getApplicationContext(), "释放控制器成功", Toast.LENGTH_SHORT).show();
                            stopTimer();
                        }

                        if (0x04 == data[5]) {
                            // 地面站控制器释放失败
                            System.out.println("地面站控制器释放失败");
                            stopTimer();
                        }
                    }
                    break;
                    case 0x20: {
                        System.out.println("机器人定时上报");
                        byte value = data[5];
                        TextView view = (TextView)findViewById(R.id.label_state);
                        if (null == view) return;
                        if (0x01 == value) {
                            view.setText(Html.fromHtml("控制端: <font color=\"#1ed76d\">主站</font>"));
                        }  if (0x02 == value) {
                            view.setText(Html.fromHtml("控制端: <font color=\"#1ed76d\">地面站</font>"));
                        } else {
                            view.setText(Html.fromHtml("控制端: <font color=\"#ff0000\">未知</font>"));
                        }

                        final String [] s = {"", "待机","前进","后退","停止","急停","充电中","过障"};
                        if (data[7] > 0 && data[7] < s.length) {
                            view = (TextView)findViewById(R.id.label_work_mode);
                            view.setText(Html.fromHtml("工作状态: <font color=\"#1ed76d\">"  + s[data[7]] + "</font>"));
                            System.out.println("工作状态：" + s[data[7]]);
                        }

                        // 更新环境信息
                        transDataToSerial(new byte[]{(byte) 0x21});
                    }
                    break;
                    case 0x21: {
                        System.out.println("环境数据上报");
                        int index = 5;
                        TextView view = (TextView)findViewById(R.id.label_wendu);
                        if (null == view) return;
                        int value = HexUtil.decode(data, index, 2); index += 2;
                        String strHtml = String.format("环境温度: <font color=\"#1ed76d\"><strong>%.1f</strong></font> ℃", value * 0.1);
                        view.setText(Html.fromHtml(strHtml));

                        view = (TextView)findViewById(R.id.label_shidu);
                        value = HexUtil.decode(data, index, 2); index += 2;
                        strHtml = String.format("环境湿度: <font color=\"#1ed76d\"><strong>%.1f</strong></font> %%", value * 0.1);
                        view.setText(Html.fromHtml(strHtml));

                        view = (TextView)findViewById(R.id.label_yaqiang);
                        value = HexUtil.decode(data, index, 4); index += 4;
                        strHtml = String.format("大气压强: <font color=\"#1ed76d\"><strong>%d</strong></font> Pa", value);
                        view.setText(Html.fromHtml(strHtml));

                        view = (TextView)findViewById(R.id.label_haiba);
                        value = HexUtil.decode(data, index, 4); index += 4;
                        strHtml = String.format("海拔: <font color=\"#1ed76d\"><strong>%d</strong></font> cm", value);
                        view.setText(Html.fromHtml(strHtml));

                        view = (TextView)findViewById(R.id.label_jindgu);
                        value = HexUtil.decode(data, index, 4); index += 4;
                        strHtml = String.format("经度: <font color=\"#1ed76d\"><strong>%.5f</strong></font>", value * 0.00001);
                        view.setText(Html.fromHtml(strHtml));

                        view = (TextView)findViewById(R.id.label_weidu);
                        value = HexUtil.decode(data, index, 4); index += 4;
                        strHtml = String.format("纬度: <font color=\"#1ed76d\"><strong>%.5f</strong></font>", value * 0.00001);
                        view.setText(Html.fromHtml(strHtml));

                        value = HexUtil.decode(data, index, 4); index += 4;
                        String strXyz = String.format("Xyz: <font color=\"#1ed76d\"><strong>%.2f,", value * 0.01);
                        value = HexUtil.decode(data, index, 4); index += 4;
                        strXyz += String.format("%.2f,", value * 0.01);
                        value = HexUtil.decode(data, index, 4);
                        strXyz += String.format("%.2f</strong></font>", value * 0.01);
                        view = (TextView)findViewById(R.id.label_xyz);
                        view.setText(Html.fromHtml(strXyz));

                        // 更新电池信息
                        transDataToSerial(new byte[]{(byte) 0x22});
                    }
                    break;
                    case 0x22: {
                        System.out.println("电池数据");
                        int index = 5;
                        TextView view = (TextView)findViewById(R.id.label_dianliang);
                        if (null == view) return;
                        String strHtml = String.format("电池电量: <font color=\"#1ed76d\"><strong>%d</strong></font> %%", data[index]);
                        view.setText(Html.fromHtml(strHtml));

                        index ++;
                        int value = HexUtil.decode(data, index, 2) & 0xffff; index += 2;
                        view = (TextView)findViewById(R.id.label_dianya);
                        strHtml = String.format("电池电压: <font color=\"#1ed76d\"><strong>%d</strong></font> mV", value);
                        view.setText(Html.fromHtml(strHtml));

                        value = HexUtil.decode(data, index, 2) & 0xffff;
                        System.out.println("电池电流: " + (short)value);
                        view = (TextView)findViewById(R.id.label_dianliu);
                        strHtml = String.format("电池电流: <font color=\"#1ed76d\"><strong>%d</strong></font> mA", (short)value);
                        view.setText(Html.fromHtml(strHtml));
                    }
                    break;
                    case 0x4E: {
                        byte[] temp = Arrays.copyOfRange(data, 6, data[5] + 6);
                        System.out.println("查询机器人设备编号: " + new String(temp));
                        TextView view = (TextView)findViewById(R.id.label_device_id);
                        if (null == view) return;
                        view.setText("设备编号:" + new String(temp));
                        isReadDevId = true;
                    }
                    break;
                    case 0xFF01: {
                        if (isVideoShow){
                            Log.e(TAG, "ideo activity is start now!");
                            return;
                        }

                        Intent intent = new Intent(MainActivity.this, VideoActivity.class);
                        startActivity(intent);
                        isVideoShow = true;
                    }
                    break;
                    case 0xFF02: {

                    }
                    break;
                    case 0xFF03: {
                        AlertDialog.Builder normalDialog = new AlertDialog.Builder(MainActivity.this);
                        normalDialog.setTitle("速度设置");
                        normalDialog.setMessage("是否修改机器人行走速度??");
                        normalDialog.setPositiveButton("确定",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        setRobotSpeed();
                                    }
                                });
                        normalDialog.setNegativeButton("取消",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        //...To-do
                                    }
                                });
                        // 显示
                        normalDialog.show();
                    }
                    break;
                    case 0xFF04: {
                        AlertDialog.Builder normalDialog = new AlertDialog.Builder(MainActivity.this);
                        normalDialog.setTitle("设备供电控制");
                        normalDialog.setMessage("是否进行设备电源控制?");
                        normalDialog.setPositiveButton("确定",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        updateDevPower();
                                    }
                                });
                        normalDialog.setNegativeButton("取消",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        //...To-do
                                    }
                                });
                        // 显示
                        normalDialog.show();
                    }
                    break;
                    case 0xFF0E: {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            updateBattery();
                        }
                    }
                    break;
                    default:
                        break;
                }
            }
        };
        // 串口
        mSerialPortMgr = new SerialPortMgr(false);
        s_mkkeys = new HashMap<Integer,Mk15Key>();
        for (int i = 0; i < 13; i++) {
            s_mkkeys.put(i, new Mk15Key(i, i < KeyId.Key_A.ordinal() ? 1500 : 1050));
        }
    }

    @SuppressLint("ObsoleteSdkInt")
    public void setHideVirtualKey(Window window){
        //保持布局状态
        int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE|
                //布局位于状态栏下方
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION|
                //全屏
                View.SYSTEM_UI_FLAG_FULLSCREEN|
                //隐藏导航栏
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        if (Build.VERSION.SDK_INT >= 19) {
            uiOptions |= 0x00001000;
        } else {
            uiOptions |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
        }
        window.getDecorView().setSystemUiVisibility(uiOptions);
        window.getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                setHideVirtualKey(window);
          }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void updateBattery() {
        Context context = getApplicationContext();
        BatteryManager manager = (BatteryManager)context.getSystemService(context.BATTERY_SERVICE);
        int currentLevel = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        DrawBatteryView batteryView = findViewById(R.id.battery_view);
        if (null == batteryView) return;
        batteryView.setElectricQuantity(currentLevel);
        TextView view = (TextView) findViewById(R.id.label_battery);
        view.setText(String.format("%d%%", currentLevel));
    }


    private void setRobotSpeed() {
        final int[] id = {0};
        final String [] s = {"速度一", "速度二", "速度三", "速度四", "速度五"};
        AlertDialog.Builder DanItem = new AlertDialog.Builder(MainActivity.this);
        DanItem.setTitle("速度设置");
        DanItem.setSingleChoiceItems(s, -1, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                id[0] = which;
            }
        }).setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (id[0]) {
                    case 0: {
                        Mk15Key.setSpeed(1000);
                    }
                    break;
                    case 1: {
                        Mk15Key.setSpeed(2000);
                    }
                    break;
                    case 2: {
                        Mk15Key.setSpeed(4000);
                    }
                    break;
                    case 3: {
                        Mk15Key.setSpeed(6000);
                    }
                    break;
                    case 4: {
                        Mk15Key.setSpeed(8000);
                    }
                    break;
                    default:
                        break;
                }

                showMessage("速度设置 " + s[id[0]] + " 完成！");
            }
        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //...To-do
            }
        });
        DanItem.create().show();
    }


    private void updateDevPower() {
        final int[] id = {0};
        final String [] s = {"打开充电", "关闭充电", "打开路由器电源", "关闭路由器电源", "打开AI盒子电源控制", "关闭AI盒子电源控制"};
        AlertDialog.Builder DanItem = new AlertDialog.Builder(MainActivity.this);
        DanItem.setTitle("开关选项");
        DanItem.setSingleChoiceItems(s, -1, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
//                ShowMessage(s[which].toString());
                id[0] = which;
            }
        }).setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                switch (id[0]) {
                    case 0: {
                        transDataToSerial(new byte[] {(byte) 0x07, (byte) 0x01});
                        showMessage("开始充电...");
                    }
                    break;
                    case 1: {
                        transDataToSerial(new byte[] {(byte) 0x07, (byte) 0x00});
                        showMessage("停止充电!");
                    }
                    break;
                    case 4: {
                        transDataToSerial(new byte[] {(byte) 0x04, (byte) 0x0C});
                        showMessage("指令已下发");
                    }
                    break;
                    case 5: {
                        transDataToSerial(new byte[] {(byte) 0x04, (byte) 0x0D});
                        showMessage("指令已下发");
                    }
                    break;
                    default:
                        showMessage("恭喜你选择了" + s[id[0]].toString());
                        break;
                }
            }
        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //...To-do
            }
        });
        DanItem.create().show();
    }

    private void showMessage(String str) {
        Toast.makeText(MainActivity.this, str, Toast.LENGTH_LONG).show();
    }


    @SuppressLint("SetTextI18n")
    private void initTextLabel() {
        TextView view = (TextView)findViewById(R.id.label_wendu);
        view.setText("环境温度: -- ℃");
        view = (TextView)findViewById(R.id.label_shidu);
        view.setText("环境湿度: -- RH%");
        view = (TextView)findViewById(R.id.label_xyz);
        view.setText("XYZ: -- ");
        view = (TextView)findViewById(R.id.label_state);
        view.setText("控制端: -");

        view = (TextView)findViewById(R.id.label_dianya);
        view.setText("电池电压: --mV");
        view = (TextView)findViewById(R.id.label_dianliu);
        view.setText("电池电流: --mA");
        view = (TextView)findViewById(R.id.label_dianliang);
        view.setText("电池电量: --%");
        view = (TextView)findViewById(R.id.label_work_mode);
        view.setText("工作状态: --");

        view = (TextView)findViewById(R.id.label_jindgu);
        view.setText("经度: 0.00000");
        view = (TextView)findViewById(R.id.label_weidu);
        view.setText("纬度: 0.00000");
        view = (TextView)findViewById(R.id.label_yaqiang);
        view.setText("大气压强: --Pa");
        view = (TextView)findViewById(R.id.label_haiba);
        view.setText("海拔: -- cm");
    }

    protected void transDataToSerial(final byte[] data) {
        byte[] cmd = new byte[6 + data.length];
        cmd[0] = (byte) 0xaa;
        cmd[1] = (byte) 0xbb;
        cmd[2] = (byte) ((data.length >> 8) & 0xff);
        cmd[3] = (byte) (data.length  & 0xff);
        System.arraycopy(data, 0, cmd, 4, data.length);
        int crc16 = HexUtil.getCRC16(cmd, data.length + 4);
        cmd[4 + data.length] = (byte) (crc16 & 0xff);
        cmd[5 + data.length] = (byte) ((crc16 >> 8) & 0xff);
        mSerialPortMgr.send(cmd);
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            updateBattery();
        }
        Logcat.d(TAG, "onStart...");
/*
        ConnectionManager.getInstance(this).checkConnectWithIntent(this.getIntent());
        ConnectionManager.getInstance(this).setRCProtocolListener(new IRCProtocolListener() {
            @Override
            public void onParam24G(Param24G param24G) {
            Log.e("24G", "======");
                showMessage("onParam24G");
            }

            @Override
            public void onParam58G(Param58G param58G) {
                showMessage("onParam58G");
                Log.e("Param58G", String.valueOf(param58G.getSignalStrength()));
            }

            @Override
            public void onDeviceInfo(DeviceInfo deviceInfo) {
                Log.e("onDeviceInfo", "======");
                showMessage("onDeviceInfo");
            }

            @Override
            public void onDecodeConfig(DecodeConfig decodeConfig) {
                showMessage("onDecodeConfig");
            }
        });
*/
        mSerialPortMgr.open(115200, new ISerialPortMgr.ReceiveCallback() {
            @Override
            public void onReceive(final byte[] data) {
//                Log.e(TAG, "onReceive: ==>> " + HexUtil.byte2HexStr(data, data.length));
                if (data.length < 6) return;

                if ((byte) 0xAA == data[0] && (byte) 0xBB == data[1] && data.length > 6) {
                    System.out.println("onReceive: ==>> " + HexUtil.byte2HexStr(data, data.length));
                    Message msg = new Message();
                    msg.what = data[4];
                    msg.obj = (Object)data;
                    mMsgHandler.sendMessage(msg);
                }

                if (0x55 == data[0] && 0x66 == data[1] && 0x42 == data[7] && data.length >= 42)
                    for (int i = 0; i < 42; i += 2) {
                        if (i < 8 || i > 32) continue;
                        int channel = ((i - 8) / 2);
                        byte[] temp = new byte[]{data[i], data[i + 1]};
                        int value = HexUtil.decode(temp, false);
                        Objects.requireNonNull(s_mkkeys.get(channel)).setValue(value, new Mk15Callback() {
                            @Override
                         public void OnClicked(int key_id, Status _state) {
                                if (KeyId.Key_A.ordinal() == key_id && Status.UpState == _state) {
                                     mMsgHandler.sendEmptyMessage(0xff01);
                                }
                                else if (KeyId.Key_B.ordinal() == key_id && Status.UpState == _state) {
                                    /* mMsgHandler.sendEmptyMessage(0xff02); */
                                }
                                else if (KeyId.Key_C.ordinal() == key_id && Status.UpState == _state) {
                                    mMsgHandler.sendEmptyMessage(0xff03);
                                }
                                else if (KeyId.Key_D.ordinal() == key_id && Status.StopState == _state) {
                                    mMsgHandler.sendEmptyMessage(0xff04);
                                }

                                byte[] cmd = KeyId.getKeyIdByIndex(key_id).getMakeRobotPackage().makePackage(_state);
                                // 转发至串口
                                if (cmd.length > 0) {
                                    transDataToSerial(cmd);
                                }
                            }
                        });
                    }
            }
        });

        // 发送数传传输指令
        byte[] buffer = HexUtil.hexStr2Bytes("556601010000004202b5c0");
        mSerialPortMgr.send(buffer);
    }

    private void startTimer(){
        if (mTimer == null) mTimer = new Timer();
        if (mTimerTask == null) {
            mTimerTask = new TimerTask() {
                @Override
                public void run() {
                    if (!isReadDevId) transDataToSerial(new byte[]{(byte) 0x4E});
                    else transDataToSerial(new byte[]{(byte) 0xee});
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        mMsgHandler.sendEmptyMessage(0xFF0E);
                    }
                }
            };
        }

        if(mTimer != null && mTimerTask != null )
            mTimer.schedule(mTimerTask, 3 * 1000, 2000);
    }

    private void stopTimer() {
        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
        }
        if (mTimerTask != null) {
            mTimerTask.cancel();
            mTimerTask = null;
        }
    }
}
